package cn.csc.module.order.web;

import cn.csc.module.order.controller.app.order.vo.AppOrderItemCreateReqVO;
import cn.csc.module.order.dal.dataobject.item.OrderItemDO;
import cn.csc.module.shoppingCard.api.card.dto.CardRespDTO;
import cn.csc.module.shoppingCard.api.transaction.dto.CardTransactionCreateReqDTO;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class javaCardTest1 {
    public static void main(String[] args) {
        // 示例SKU列表
        // 初始化购物卡（按使用顺序）
        List<CardRespDTO> cardList  = new ArrayList<>();
        CardRespDTO c1= new CardRespDTO();
        c1.setId(new BigInteger("1"));
        c1.setBalance(new BigDecimal(101));//309.1
        CardRespDTO c2= new CardRespDTO();
        c2.setId(new BigInteger("2"));
        c2.setBalance(new BigDecimal(50));//100
        CardRespDTO c3= new CardRespDTO();
        c3.setId(new BigInteger("3"));
        c3.setBalance(new BigDecimal(100));//100
        cardList.add(c1); // 单价100，数量2
//        cardList.add(c2); // 单价200，数量1
//        cardList.add(c3); // 单价200，数量1
        // 初始化订单（总金额400元）
        List<AppOrderItemCreateReqVO>  orders= new ArrayList<>();
        AppOrderItemCreateReqVO vo1= new AppOrderItemCreateReqVO(); // 占比37.5%
        vo1.setId(new BigInteger("1"));
        vo1.setTotal(new BigDecimal(100));//118
        vo1.setRemaining(vo1.getTotal());
        AppOrderItemCreateReqVO vo2= new AppOrderItemCreateReqVO(); // 占比62.5%
        vo2.setId(new BigInteger("2"));
        vo2.setTotal(new BigDecimal(100));//10.9
        AppOrderItemCreateReqVO vo3= new AppOrderItemCreateReqVO(); // 占比62.5%
        vo3.setId(new BigInteger("3"));
        vo3.setTotal(new BigDecimal(100));//19.9
//        AppOrderItemCreateReqVO vo4= new AppOrderItemCreateReqVO(); // 占比62.5%
//        vo4.setId(new BigInteger("4"));
//        vo4.setTotal(new BigDecimal(99));//20.8
        orders.add(vo1);
        orders.add(vo2);
        orders.add(vo3);
//        orders.add(vo4);

//         distributeGiftCards(orders,cardList);
        // 打印分配结果
        // 执行分配
        allocate(orders, cardList);
        System.out.println("=== 订单分配明细 ===");
        orders.forEach(order -> {
            System.out.printf("订单 %s（总额%.2f）%n", order.getId(), order.getTotal());
            order.getCardUsage().forEach(allocation ->
                    System.out.printf("  ▸ %s 支付 %.2f 元%n",
                            allocation.getCardId(), allocation.getAmount()));
            System.out.printf("剩余应支付: %.2f%n%n", order.getRemaining());
        });

        System.out.println("=== 购物卡余额 ===");
        cardList.forEach(card ->
                System.out.printf("%s 剩余 %.2f 元%n", card.getId(), card.getBalance()));

//        // 打印结果验证
//        System.out.println("=== 购物卡剩余余额 ===");
//        cardList.forEach(card -> System.out.printf("卡号 %s ➔ 剩余 %.2f 元%n",
//                card.getId(), card.getBalance()));
//
//        System.out.println("\n=== 订单分配明细 ===");
//        orders.forEach(order -> {
//            System.out.printf("订单 "+order.getId()+"（总金额"+order.getTotal()+ "元）使用的总金额 "+order.getCardUsage().stream().map(CardTransactionCreateReqDTO::getAmount).reduce(BigDecimal.ZERO,BigDecimal::add)+ "%n");
//            order.getCardUsage().forEach(allocation ->
//                    System.out.printf("  ▸ 使用卡号 %s 支付 %s 元 订单Id %s  %n",
//                            allocation.getCardId(), allocation.getAmount(),order.getId()));
//        });
    }
    public static void allocate(List<AppOrderItemCreateReqVO> orders, List<CardRespDTO> cards) {
//        BigDecimal totalRemaining = calculateTotalRemaining(orders);
        // 计算初始总剩余金额
        List<OrderItemDO> dtoList = new ArrayList<>();
        OrderItemDO ss = new OrderItemDO();
        ss.setId(new BigInteger("1"));
        dtoList.add(ss);
        OrderItemDO ss1 = new OrderItemDO();
        ss1.setId(new BigInteger("2"));
        dtoList.add(ss1);
        OrderItemDO ss3 = new OrderItemDO();
        ss3.setId(new BigInteger("3"));
        dtoList.add(ss3);
//        OrderItemDO ss4 = new OrderItemDO();
//        ss4.setId(new BigInteger("4"));
//        dtoList.add(ss4);
        orders= mapFields(dtoList,orders);

        BigDecimal totalRemaining = orders.stream()
                .map(o -> o.getRemaining())
                .reduce(BigDecimal.ZERO, BigDecimal::add);


        for (CardRespDTO card : cards) {
            if (totalRemaining.compareTo(BigDecimal.ZERO) <= 0) break;

            // 当前卡可分配上限
            BigDecimal cardLimit = card.getBalance().min(totalRemaining);

            for (AppOrderItemCreateReqVO order : orders) {
                if (cardLimit.compareTo(BigDecimal.ZERO) <= 0) break;

                // 计算当前订单分配比例（保留6位小数）
                System.out.println("订单："+order.getId()+"=== order.getRemaining:"+order.getRemaining()+"==totalRemaining:"+totalRemaining);
                System.out.println("卡："+card.getId()+"=== cardLimit:"+cardLimit);
                BigDecimal allocAmount =BigDecimal.ZERO;

                System.out.println("getTotal："+order.getTotal()+"==totalRemaining:"+totalRemaining+"=== cardLimit:"+cardLimit);
                    BigDecimal ratio = order.getTotal().divide(totalRemaining, 6, RoundingMode.HALF_UP);
                System.out.println("卡getBalance："+card.getBalance()+"==ratio:"+ratio+"=== cardLimit:"+cardLimit);
                    allocAmount = card.getBalance().multiply(ratio).setScale(2, RoundingMode.HALF_UP);
                System.out.println("卡getBalance："+card.getBalance()+"=== cardLimit:"+cardLimit);

                // 防止超额分配
                allocAmount = allocAmount.min(order.getRemaining());

                // 记录分配并更新状态
                if (allocAmount.compareTo(BigDecimal.ZERO) > 0) {
                    CardTransactionCreateReqDTO cardu=new CardTransactionCreateReqDTO();
                    cardu.setCardId(card.getId());
                    cardu.setAmount(allocAmount);
                    List <CardTransactionCreateReqDTO> s=order.getCardUsage()!=null?order.getCardUsage(): new ArrayList<>();
                    s.add(cardu);
                    order.setCardUsage(s);

                    order.setRemaining(order.getRemaining().subtract(allocAmount)) ;
                    cardLimit = cardLimit.subtract(allocAmount);
                }
            }

        }
        for (CardRespDTO card : cards) {
            // 筛选出id等于1的卡片，但不直接修改原列表
            List <CardTransactionCreateReqDTO> filteredCards = orders.stream()
                    .flatMap(item -> item.getCardUsage().stream().filter(c -> c.getCardId()==card.getId())) // 将每个AppOrderItemCreateReqVO中的List<CardRespDTO>展平
                    .collect(Collectors.toList());
            //分配的购物卡支付的总金额
            BigDecimal total = filteredCards.stream().map(CardTransactionCreateReqDTO::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
           // 取出购物卡使用过的订单的总金额
            List<BigInteger> itemIds = filteredCards.stream().map(CardTransactionCreateReqDTO::getRelatedOrderItem).collect(Collectors.toList());

            //购物卡的总金额
            BigDecimal tranTotalAmt =card.getBalance();
            //取出最大的金额的数据
            Optional<CardTransactionCreateReqDTO> maxTransaction = filteredCards.stream()
                    .filter(dto -> dto.getAmount() != null) // 过滤空金额
                    .max(Comparator.comparing(CardTransactionCreateReqDTO::getAmount)); // 用BigDecimal的compareTo比较

            // TODO BigDecimal四舍五入会造成子丁订单金额之和大于分账总金额
            //已分配的金额>购物卡金额 ，减去多余的金额
            if (total.compareTo(tranTotalAmt) > 0){

                BigDecimal diff = total.subtract(tranTotalAmt);
                // 获取结果并修改（示例：标记为最大值）
                if (maxTransaction.isPresent()) {
                    CardTransactionCreateReqDTO maxDto = maxTransaction.get();
                    // 进行修改操作（例如：修改金额或添加标记字段）
                    maxDto.setAmount(maxDto.getAmount().subtract(diff));
                }
                // TODO BigDecimal 100 分3个订单分不尽的情况
                //分配的购物卡支付的总金额 小于购物卡的金额，并且 购物卡的金额小于订单的总金额 处理 0.01 用不掉的情况
            }else if(total.compareTo(tranTotalAmt)<0 ){
                BigDecimal diff = tranTotalAmt.subtract(total);
                 if(tranTotalAmt.compareTo(totalRemaining)<0 && diff.compareTo(new BigDecimal("0.01"))==0){
//                     BigDecimal diff = tranTotalAmt.subtract(total);
                     // 获取结果并修改（示例：标记为最大值）
                     if (maxTransaction.isPresent()) {
                         CardTransactionCreateReqDTO maxDto = maxTransaction.get();
                         // 进行修改操作（例如：修改金额或添加标记字段）
                         maxDto.setAmount(maxDto.getAmount().add(diff));

                     }
                 }else{
                     //并且 分配的购物卡支付的订单总金额 小于 订单的应付金额
                     for(AppOrderItemCreateReqVO orderVo:orders){
                         //订单分配的购物卡金额
                         BigDecimal orderAmt= orderVo.getCardUsage().stream().map(CardTransactionCreateReqDTO::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                         //订单分配的购物卡金额 小于订单的应付金额
                         if(orderAmt.compareTo(orderVo.getTotal())<0 ){
                             BigDecimal diff1 = orderVo.getTotal().subtract(orderAmt);
                             // 获取结果并修改（示例：标记为最大值）
                             if (maxTransaction.isPresent()) {
                                 CardTransactionCreateReqDTO maxDto = maxTransaction.get();
                                 // 进行修改操作（例如：修改金额或添加标记字段）
                                 maxDto.setAmount(maxDto.getAmount().add(diff1));

                             }
                         }

                     }
                 }


            }
        }


    }
    public static List<AppOrderItemCreateReqVO> mapFields(List<OrderItemDO> dtoList, List<AppOrderItemCreateReqVO> entityList) {
        // 校验列表大小
        if (dtoList.size() != entityList.size()) {
            throw new IllegalArgumentException("列表大小必须一致");
        }

        // 按索引遍历，直接修改 entityList 中的对象
        IntStream.range(0, dtoList.size()).forEach(i -> {
            OrderItemDO dto = dtoList.get(i);
            AppOrderItemCreateReqVO entity = entityList.get(i);
//            entity.setTotal(dto.getSpuTotalAmount());
//            entity.setId(dto.getId());
            entity.setRemaining(entity.getTotal());
        });

        return entityList;
    }
    private static List<AppOrderItemCreateReqVO> getActiveOrders(List<AppOrderItemCreateReqVO> orders) {
        List<AppOrderItemCreateReqVO> activeOrders = new ArrayList<>();

        for (AppOrderItemCreateReqVO order : orders) {
            // 剩余金额 > 0 判定为有效订单
            if (order.getRemaining().compareTo(BigDecimal.ZERO) > 0) {
                activeOrders.add(order);
            }
        }
        return activeOrders;
    }

}
